home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_emacs.idb / usr / freeware / share / emacs / 19.34 / lisp / ediff-init.el.z / ediff-init.el
Encoding:
Text File  |  1998-10-28  |  57.4 KB  |  1,522 lines

  1. ;;; ediff-init.el --- Macros, variables, and defsubsts used by Ediff
  2.  
  3. ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
  6.  
  7. ;; This file is part of GNU Emacs.
  8.  
  9. ;; GNU Emacs is free software; you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation; either version 2, or (at your option)
  12. ;; any later version.
  13.  
  14. ;; GNU Emacs is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;; GNU General Public License for more details.
  18.  
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  21. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  22. ;; Boston, MA 02111-1307, USA.
  23.  
  24. ;;; Code:
  25.  
  26. ;; Start compiler pacifier
  27. (defvar ediff-metajob-name)
  28. (defvar ediff-meta-buffer)
  29. (defvar pm-color-alist)
  30. (defvar ediff-grab-mouse)
  31. (defvar ediff-mouse-pixel-position)
  32. (defvar ediff-mouse-pixel-threshold)
  33. (defvar ediff-whitespace)
  34. (defvar ediff-multiframe)
  35. ;; end pacifier
  36.  
  37. ;; Is it XEmacs?
  38. (defconst ediff-xemacs-p (string-match "XEmacs" emacs-version))
  39. ;; Is it Emacs?
  40. (defconst ediff-emacs-p (not ediff-xemacs-p))
  41.  
  42. (defvar ediff-force-faces nil
  43.   "If t, Ediff will think that it is running on a display that supports faces.
  44. This is provided as a temporary relief for users of face-capable displays
  45. that Ediff doesn't know about.")
  46.  
  47. ;; Are we running as a window application or on a TTY?
  48. (defsubst ediff-device-type ()
  49.   (if ediff-emacs-p
  50.       window-system
  51.     (device-type (selected-device))))
  52.  
  53. ;; in XEmacs: device-type is tty on tty and stream in batch.
  54. (defun ediff-window-display-p ()
  55.   (and (ediff-device-type) (not (memq (ediff-device-type) '(tty pc stream)))))
  56.  
  57. ;; test if supports faces
  58. ;; ediff-force-faces is for those devices that support faces, but we don't know
  59. ;; this yet
  60. (defun ediff-has-face-support-p ()
  61.   (cond ((ediff-window-display-p))
  62.     (ediff-force-faces)
  63.     (ediff-emacs-p (memq (ediff-device-type) '(pc)))
  64.     (ediff-xemacs-p (memq (ediff-device-type) '(tty pc)))))
  65.   
  66.   
  67. ;; Defines SYMBOL as an advertised local variable.  
  68. ;; Performs a defvar, then executes `make-variable-buffer-local' on
  69. ;; the variable.  Also sets the `permanent-local' property,
  70. ;; so that `kill-all-local-variables' (called by major-mode setting
  71. ;; commands) won't destroy Ediff control variables.
  72. ;; 
  73. ;; Plagiarised from `emerge-defvar-local' for XEmacs.
  74. (defmacro ediff-defvar-local (var value doc) 
  75.   (` (progn
  76.        (defvar (, var) (, value) (, doc))
  77.        (make-variable-buffer-local '(, var))
  78.        (put '(, var) 'permanent-local t))))
  79.     
  80.  
  81.  
  82. ;; Variables that control each Ediff session---local to the control buffer.
  83.  
  84. ;; Mode variables
  85. ;; The buffer in which the A variant is stored.
  86. (ediff-defvar-local ediff-buffer-A nil "")
  87. ;; The buffer in which the B variant is stored.
  88. (ediff-defvar-local ediff-buffer-B nil "")
  89. ;; The buffer in which the C variant is stored.
  90. (ediff-defvar-local ediff-buffer-C nil "")
  91. ;; Ancestor buffer
  92. (ediff-defvar-local ediff-ancestor-buffer nil "")
  93. ;; The control buffer of ediff.
  94. (ediff-defvar-local ediff-control-buffer nil "")
  95.  
  96. ;;; Macros
  97. (defmacro ediff-odd-p (arg)
  98.   (` (eq (logand (, arg) 1) 1)))
  99.  
  100. (defmacro ediff-buffer-live-p (buf)
  101.   (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf))))))
  102.  
  103. (defmacro ediff-get-buffer (arg)
  104.   (` (cond ((eq (, arg) 'A) ediff-buffer-A)
  105.        ((eq (, arg) 'B) ediff-buffer-B)
  106.        ((eq (, arg) 'C) ediff-buffer-C)
  107.        ((eq (, arg) 'Ancestor) ediff-ancestor-buffer)
  108.        )
  109.   ))
  110.   
  111. (defmacro ediff-get-value-according-to-buffer-type (buf-type list)
  112.   (` (cond ((eq (, buf-type) 'A) (nth 0 (, list)))
  113.        ((eq (, buf-type) 'B) (nth 1 (, list)))
  114.        ((eq (, buf-type) 'C) (nth 2 (, list))))))
  115.        
  116. (defmacro ediff-char-to-buftype (arg)
  117.   (` (cond ((memq (, arg) '(?a ?A)) 'A)
  118.        ((memq (, arg) '(?b ?B)) 'B)
  119.        ((memq (, arg) '(?c ?C)) 'C)
  120.        )
  121.   ))
  122.   
  123. (defmacro ediff-get-difference (n buf-type)
  124.   (` (aref
  125.       (symbol-value
  126.        (intern (format "ediff-difference-vector-%S" (, buf-type)))) (, n))))
  127.   
  128. ;; tell if it has been previously determined that the region has
  129. ;; no diffs other than the white space and newlines
  130. ;; The argument, N, is the diff region number used by Ediff to index the
  131. ;; diff vector. It is 1 less than the number seen by the user.
  132. ;;
  133. ;; A difference vector has the form:
  134. ;; [diff diff diff ...]
  135. ;; where each diff has the form:
  136. ;; [overlay fine-diff-vector no-fine-diffs-flag]
  137. ;; fine-diff-vector is a vector [fine-diff fine-diff fine-diff ...]
  138. (defmacro ediff-no-fine-diffs-p (n)
  139.   (` (aref (ediff-get-difference (, n) 'A) 2)))
  140.   
  141. (defmacro ediff-get-diff-overlay-from-diff-record (diff-rec)
  142.   (` (aref (, diff-rec) 0)))
  143.   
  144. (defmacro ediff-get-diff-overlay (n buf-type)  
  145.   (` (ediff-get-diff-overlay-from-diff-record
  146.       (ediff-get-difference (, n) (, buf-type)))))
  147.  
  148. (defmacro ediff-get-fine-diff-vector-from-diff-record (diff-rec)
  149.   (` (aref (, diff-rec) 1)))
  150.       
  151. (defmacro ediff-set-fine-diff-vector (n buf-type fine-vec)
  152.   (` (aset (ediff-get-difference (, n) (, buf-type)) 1 (, fine-vec))))
  153.   
  154. (defmacro ediff-get-state-of-diff (n buf-type)
  155.   (` (if (ediff-buffer-live-p ediff-buffer-C)
  156.      (aref (ediff-get-difference (, n) (, buf-type)) 3))))
  157. (defmacro ediff-set-state-of-diff (n buf-type val)
  158.   (` (aset (ediff-get-difference (, n) (, buf-type)) 3 (, val))))
  159. (defmacro ediff-get-state-of-merge (n)
  160.   (` (if ediff-state-of-merge
  161.      (aref (aref ediff-state-of-merge (, n)) 0))))
  162. (defmacro ediff-get-state-of-ancestor (n)
  163.   (` (if ediff-state-of-merge
  164.      (aref (aref ediff-state-of-merge (, n)) 1))))
  165. (defmacro ediff-set-state-of-merge (n val)
  166.   (` (if ediff-state-of-merge
  167.      (aset (aref ediff-state-of-merge (, n)) 0 (, val)))))
  168.  
  169. ;; if flag is t, puts a mark on diff region saying that 
  170. ;; the differences are in white space only. If flag is nil,
  171. ;; the region is marked as essential (i.e., differences are
  172. ;; not just in the white space and newlines.)
  173. (defmacro ediff-mark-diff-as-space-only (n flag)
  174.   (` (aset (ediff-get-difference (, n) 'A) 2 (, flag))))
  175.   
  176. (defmacro ediff-get-fine-diff-vector (n buf-type)
  177.   (` (ediff-get-fine-diff-vector-from-diff-record
  178.       (ediff-get-difference (, n) (, buf-type)))))
  179.   
  180. ;; Macro to switch to BUFFER, evaluate FORMS, returns to original buffer.
  181. ;; Differs from `save-excursion' in that it doesn't save the point and mark.
  182. ;; This is essentially `emerge-eval-in-buffer' with the test for live buffers."
  183. (defmacro ediff-eval-in-buffer (buffer &rest forms)
  184.   (` (let ((StartBuffer (current-buffer)))
  185.        (if (ediff-buffer-live-p (, buffer))
  186.        (unwind-protect
  187.            (progn
  188.          (set-buffer (, buffer))
  189.          (,@ forms))
  190.          (set-buffer StartBuffer))
  191.      (or (eq this-command 'ediff-quit)
  192.          (error ediff-KILLED-VITAL-BUFFER))
  193.      ))))
  194.      
  195.  
  196. (defsubst ediff-multiframe-setup-p ()
  197.   (and (ediff-window-display-p) ediff-multiframe))
  198.              
  199. (defmacro ediff-narrow-control-frame-p ()
  200.   (` (and (ediff-multiframe-setup-p)
  201.       (equal ediff-help-message ediff-brief-message-string))))
  202.       
  203. (defmacro ediff-3way-comparison-job ()
  204.   (` (memq
  205.       ediff-job-name
  206.       '(ediff-files3 ediff-buffers3))))
  207. (ediff-defvar-local ediff-3way-comparison-job nil "")
  208.       
  209. (defmacro ediff-merge-job ()
  210.   (` (memq
  211.       ediff-job-name
  212.       '(ediff-merge-files
  213.     ediff-merge-buffers
  214.     ediff-merge-files-with-ancestor
  215.     ediff-merge-buffers-with-ancestor
  216.     ediff-merge-revisions
  217.     ediff-merge-revisions-with-ancestor))))
  218. (ediff-defvar-local ediff-merge-job nil "")
  219.  
  220. (defmacro ediff-merge-with-ancestor-job ()
  221.   (` (memq
  222.       ediff-job-name
  223.       '(ediff-merge-files-with-ancestor
  224.     ediff-merge-buffers-with-ancestor
  225.     ediff-merge-revisions-with-ancestor))))
  226. (ediff-defvar-local ediff-merge-with-ancestor-job nil "")
  227.  
  228. (defmacro ediff-3way-job ()
  229.   (` (or ediff-3way-comparison-job ediff-merge-job)))
  230. (ediff-defvar-local ediff-3way-job nil "")
  231.  
  232. ;; A diff3 job is like a 3way job, but ediff-merge doesn't require the use
  233. ;; of diff3.
  234. (defmacro ediff-diff3-job ()
  235.   (` (or ediff-3way-comparison-job
  236.      ediff-merge-with-ancestor-job)))
  237. (ediff-defvar-local ediff-diff3-job nil "")
  238.      
  239. (defmacro ediff-windows-job ()
  240.   (` (memq ediff-job-name '(ediff-windows-wordwise ediff-windows-linewise))))
  241. (ediff-defvar-local ediff-windows-job nil "")
  242.  
  243. (defmacro ediff-word-mode-job ()
  244.   (` (memq ediff-job-name '(ediff-windows-wordwise  ediff-regions-wordwise))))
  245. (ediff-defvar-local ediff-word-mode-job nil "")
  246.  
  247. (defmacro ediff-narrow-job ()
  248.   (` (memq ediff-job-name '(ediff-windows-wordwise
  249.                 ediff-regions-wordwise
  250.                 ediff-windows-linewise
  251.                 ediff-regions-linewise))))
  252. (ediff-defvar-local ediff-narrow-job nil "")
  253.  
  254. ;; Note: ediff-merge-directory-revisions-with-ancestor is not treated as an
  255. ;; ancestor metajob, since it behaves differently.
  256. (defsubst ediff-ancestor-metajob (&optional metajob)
  257.   (memq (or metajob ediff-metajob-name)
  258.     '(ediff-merge-directories-with-ancestor
  259.       ediff-merge-filegroups-with-ancestor)))
  260. (defsubst ediff-revision-metajob (&optional metajob)
  261.   (memq (or metajob ediff-metajob-name)
  262.     '(ediff-directory-revisions 
  263.       ediff-merge-directory-revisions
  264.       ediff-merge-directory-revisions-with-ancestor)))
  265. (defsubst ediff-patch-metajob (&optional metajob)
  266.   (memq (or metajob ediff-metajob-name)
  267.     '(ediff-multifile-patch)))
  268. ;; metajob involving only one group of files, such as multipatch or directory
  269. ;; revision
  270. (defsubst ediff-one-filegroup-metajob (&optional metajob)
  271.   (or (ediff-revision-metajob metajob)
  272.       (ediff-patch-metajob metajob)
  273.       ;; add more here
  274.       ))
  275. (defsubst ediff-collect-diffs-metajob (&optional metajob)
  276.   (memq (or metajob ediff-metajob-name)
  277.     '(ediff-directories
  278.       ediff-directory-revisions
  279.       ediff-merge-directories
  280.       ediff-merge-directories-with-ancestor
  281.       ediff-merge-directory-revisions
  282.       ediff-merge-directory-revisions-with-ancestor
  283.       ;; add more here
  284.       )))
  285.  
  286. (defsubst ediff-metajob3 (&optional metajob)
  287.   (memq (or metajob ediff-metajob-name)
  288.     '(ediff-merge-directories-with-ancestor
  289.       ediff-merge-filegroups-with-ancestor 
  290.       ediff-directories3
  291.       ediff-filegroups3)))
  292. (defsubst ediff-comparison-metajob3 (&optional metajob)
  293.   (memq (or metajob ediff-metajob-name)
  294.     '(ediff-directories3 ediff-filegroups3)))
  295.  
  296. (defsubst ediff-barf-if-not-control-buffer (&optional meta-buf)
  297.   (or (eq (if meta-buf ediff-meta-buffer ediff-control-buffer)
  298.       (current-buffer))
  299.       (error "%S: This command runs in Ediff Control Buffer only!"
  300.          this-command)))
  301.  
  302.  
  303. ;; Hook variables
  304.  
  305. (defvar ediff-before-setup-windows-hook nil
  306.   "*Hooks to run before Ediff sets its window configuration. 
  307. This can be used to save the previous window config, which can be restored
  308. on ediff-quit or ediff-suspend.") 
  309. (defvar ediff-after-setup-windows-hook nil
  310.   "*Hooks to run after Ediff sets its window configuration. 
  311. This can be used to set up control window or icon in a desired place.")
  312. (defvar ediff-before-setup-control-frame-hook nil
  313.   "*Hooks run before setting up the frame to display Ediff Control Panel.
  314. Can be used to change control frame parameters to position it where it
  315. is desirable.")
  316. (defvar ediff-after-setup-control-frame-hook nil
  317.   "*Hooks run after setting up the frame to display Ediff Control Panel.
  318. Can be used to move the frame where it is desired.")
  319. (defvar ediff-startup-hook nil
  320.   "*Hooks to run in the control buffer after Ediff has been set up.")
  321. (defvar ediff-select-hook nil
  322.   "*Hooks to run after a difference has been selected.")
  323. (defvar ediff-unselect-hook nil
  324.   "*Hooks to run after a difference has been unselected.")
  325. (defvar ediff-prepare-buffer-hook  nil
  326.   "*Hooks called after buffers A, B, and C are set up.")
  327. (defvar ediff-load-hook nil
  328.   "*Hook run after Ediff is loaded.  Can be used to change defaults.")
  329.   
  330. (defvar ediff-mode-hook nil
  331.   "*Hook run just after ediff-mode is set up in the control buffer. 
  332. This is done before any windows or frames are created. One can use it to
  333. set local variables that determine how the display looks like.")
  334. (defvar ediff-keymap-setup-hook nil
  335.   "*Hook run just after the default bindings in Ediff keymap are set up.")
  336.   
  337. (defvar ediff-display-help-hook nil
  338.   "*Hooks run after preparing the help message.")
  339.  
  340. (defvar ediff-suspend-hook (list 'ediff-default-suspend-function)
  341.   "*Hooks to run in the Ediff control buffer when Ediff is suspended.")
  342. (defvar ediff-quit-hook (list 'ediff-cleanup-mess)
  343.   "*Hooks to run in the Ediff control buffer after finishing Ediff.") 
  344. (defvar ediff-cleanup-hook nil
  345.   "*Hooks to run on exiting Ediff but before killing the control buffer.
  346. This is a place to do various cleanups, such as deleting the variant buffers.
  347. Ediff provides a function, `ediff-janitor', as one such possible hook.")
  348.  
  349.  
  350. ;; Help messages
  351.  
  352. (defconst ediff-long-help-message-head
  353.   "   Moving around     |     Toggling features     |       Manipulations
  354. =====================|===========================|============================="
  355.   "The head of the full help message.")
  356. (defconst ediff-long-help-message-tail
  357.   "=====================|===========================|=============================
  358.     R -show registry |                           |  M   -show session group
  359.     D -diff output   |     E -browse Ediff manual|  G   -send bug report   
  360.     i -status info   |     ? -help off           |  z/q -suspend/quit
  361. -------------------------------------------------------------------------------
  362. X,Y (x,y)  on the left are meta-symbols for the keys  A,B,C (a,b,c).
  363. X,Y on the right are meta-symbols for buffers A,B,C.
  364. A,B,C on the right denote the working buffers A,B,C, respectively."
  365.   "The tail of the full-help message.")
  366.  
  367. (defconst ediff-long-help-message-compare3
  368.   "
  369. p,DEL -previous diff |     | -vert/horiz split   | xy -copy buf X's region to Y
  370. n,SPC -next diff     |     h -hiliting           | rx -restore buf X's old diff
  371.     j -jump to diff  |     @ -auto-refinement    |  * -refine current region
  372.    gx -goto X's point|                           |  ! -update diff regions
  373.   C-l -recenter      |    ## -ignore whitespace  |
  374.   v/V -scroll up/dn  | #f/#h -focus/hide regions | wx -save buf X
  375.   </> -scroll lt/rt  |     X -read-only in buf X | wd -save diff output
  376.                      |     m -wide display       |  ~ -rotate buffers
  377. "
  378.   "Help message usually used for 3-way comparison.
  379. Normally, not a user option. See `ediff-help-message' for details.")
  380.   
  381. (defconst ediff-long-help-message-compare2
  382.   "
  383. p,DEL -previous diff |     | -vert/horiz split   |a/b -copy A/B's region to B/A
  384. n,SPC -next diff     |     h -hiliting           | rx -restore buf X's old diff
  385.     j -jump to diff  |     @ -auto-refinement    |  * -refine current region
  386.    gx -goto X's point|                           |  ! -update diff regions
  387.   C-l -recenter      |    ## -ignore whitespace  |
  388.   v/V -scroll up/dn  | #f/#h -focus/hide regions | wx -save buf X
  389.   </> -scroll lt/rt  |     X -read-only in buf X | wd -save diff output
  390.     ~ -swap variants |     m -wide display       |  
  391. "
  392.   "Help message usually used for 2-way comparison.
  393. Normally, not a user option. See `ediff-help-message' for details.")
  394.   
  395. (defconst ediff-long-help-message-narrow2
  396.   "
  397. p,DEL -previous diff |     | -vert/horiz split   |a/b -copy A/B's region to B/A
  398. n,SPC -next diff     |     h -hiliting           | rx -restore buf X's old diff
  399.     j -jump to diff  |     @ -auto-refinement    |  * -refine current region
  400.    gx -goto X's point|     % -narrow/widen buffs |  ! -update diff regions
  401.   C-l -recenter      |    ## -ignore whitespace  |
  402.   v/V -scroll up/dn  | #f/#h -focus/hide regions | wx -save buf X
  403.   </> -scroll lt/rt  |     X -read-only in buf X | wd -save diff output
  404.     ~ -swap variants |     m -wide display       |  
  405. "
  406.   "Help message when comparing windows or regions line-by-line.
  407. Normally, not a user option. See `ediff-help-message' for details.")
  408.   
  409. (defconst ediff-long-help-message-word-mode
  410.   "
  411. p,DEL -previous diff |     | -vert/horiz split   | xy -copy buf X's region to Y
  412. n,SPC -next diff     |     h -hiliting           | rx -restore buf X's old diff
  413.     j -jump to diff  |                           |                   
  414.    gx -goto X's point|     % -narrow/widen buffs |  ! -recompute diffs
  415.   C-l -recenter      |                           |
  416.   v/V -scroll up/dn  | #f/#h -focus/hide regions | wx -save buf X
  417.   </> -scroll lt/rt  |     X -read-only in buf X | wd -save diff output
  418.     ~ -swap variants |     m -wide display       |  
  419. "
  420.   "Help message when comparing windows or regions word-by-word.
  421. Normally, not a user option. See `ediff-help-message' for details.")
  422.   
  423. (defconst ediff-long-help-message-merge
  424.   "
  425. p,DEL -previous diff |     | -vert/horiz split   |  x -copy buf X's region to C
  426. n,SPC -next diff     |     h -hiliting           |  r -restore buf C's old diff
  427.     j -jump to diff  |     @ -auto-refinement    |  * -refine current region
  428.    gx -goto X's point|    ## -ignore whitespace  |  ! -update diff regions
  429.   C-l -recenter      | #f/#h -focus/hide regions |  + -combine diff regions
  430.   v/V -scroll up/dn  |     X -read-only in buf X | wx -save buf X
  431.   </> -scroll lt/rt  |     m -wide display       | wd -save diff output
  432.     ~ -swap variants |     s -shrink window C    |  / -show ancestor buff 
  433.                      |     $ -show clashes only  |  & -merge w/new default
  434. "
  435.   "Help message during merging.
  436. Normally, not a user option. See `ediff-help-message' for details.")
  437.  
  438. ;; The actual long help message.
  439. (ediff-defvar-local ediff-long-help-message ""
  440.   "Normally, not a user option. See `ediff-help-message' for details.")
  441.   
  442. (defconst ediff-brief-message-string
  443.   "  ? - help  "
  444.   "Contents of the brief help message.")
  445. ;; The actual brief help message
  446. (ediff-defvar-local ediff-brief-help-message ""
  447.   "Normally, not a user option. See `ediff-help-message' for details.")
  448.   
  449. (ediff-defvar-local ediff-brief-help-message-function nil
  450.   "The brief help message that the user can customize.
  451. If the user sets this to a parameter-less function, Ediff will use it to
  452. produce the brief help message. This function must return a string.")
  453. (ediff-defvar-local ediff-long-help-message-function nil
  454.   "The long help message that the user can customize.
  455. See `ediff-brief-help-message-function' for more.")
  456.  
  457. (defvar ediff-use-long-help-message nil
  458.   "*If t, Ediff displays a long help message. Short help message otherwise.")
  459.  
  460. ;; The actual help message.
  461. (ediff-defvar-local ediff-help-message ""
  462.   "The actual help message.
  463. Normally, the user shouldn't touch this. However, if you want Ediff to
  464. start up with different help messages for different jobs, you can change
  465. the value of this variable and the variables `ediff-help-message-*' in
  466. `ediff-startup-hook'.") 
  467.  
  468. ;; Error messages
  469. (defconst ediff-KILLED-VITAL-BUFFER
  470.   "You have killed a vital Ediff buffer---you must leave Ediff now!")
  471. (defconst ediff-NO-DIFFERENCES
  472.   "Sorry, comparison of identical variants is not what I am made for...")
  473. (defconst ediff-BAD-DIFF-NUMBER
  474.   ;; %S stands for this-command, %d - diff number, %d - max diff
  475.   "%S: Bad diff region number, %d. Valid numbers are 1 to %d")
  476.  
  477. ;; Selective browsing
  478.  
  479. (ediff-defvar-local ediff-skip-diff-region-function 'ediff-show-all-diffs
  480.   "Function that determines the next/previous diff region to show.
  481. Should return t for regions to be ignored and nil otherwise.
  482. This function gets a region number as an argument. The region number
  483. is the one used internally by Ediff. It is 1 less than the number seen
  484. by the user.")
  485.  
  486. (ediff-defvar-local ediff-hide-regexp-matches-function
  487.   'ediff-hide-regexp-matches 
  488.   "Function to use in determining which regions to hide.
  489. See the documentation string of `ediff-hide-regexp-matches' for details.")
  490. (ediff-defvar-local ediff-focus-on-regexp-matches-function
  491.   'ediff-focus-on-regexp-matches
  492.   "Function to use in determining which regions to focus on.
  493. See the documentation string of `ediff-focus-on-regexp-matches' for details.")
  494.  
  495. ;; Regexp that determines buf A regions to focus on when skipping to diff
  496. (ediff-defvar-local ediff-regexp-focus-A "" "")
  497. ;; Regexp that determines buf B regions to focus on when skipping to diff
  498. (ediff-defvar-local ediff-regexp-focus-B "" "")
  499. ;; Regexp that determines buf C regions to focus on when skipping to diff
  500. (ediff-defvar-local ediff-regexp-focus-C "" "")
  501. ;; connective that determines whether to focus regions that match both or
  502. ;; one of the regexps
  503. (ediff-defvar-local ediff-focus-regexp-connective 'and "")
  504.   
  505. ;; Regexp that determines buf A regions to ignore when skipping to diff
  506. (ediff-defvar-local ediff-regexp-hide-A "" "")
  507. ;; Regexp that determines buf B regions to ignore when skipping to diff
  508. (ediff-defvar-local ediff-regexp-hide-B "" "")
  509. ;; Regexp that determines buf C regions to ignore when skipping to diff
  510. (ediff-defvar-local ediff-regexp-hide-C "" "")
  511. ;; connective that determines whether to hide regions that match both or
  512. ;; one of the regexps
  513. (ediff-defvar-local ediff-hide-regexp-connective 'and "")
  514.   
  515.   
  516. (defvar ediff-ange-ftp-ftp-name (if ediff-xemacs-p
  517.                     'ange-ftp-ftp-path
  518.                   'ange-ftp-ftp-name)
  519.   "Function ange-ftp uses to find out if file is remote.")
  520.   
  521.  
  522. ;; Copying difference regions between buffers.    
  523. (ediff-defvar-local ediff-killed-diffs-alist nil
  524.   "A list of killed diffs. 
  525. A diff is saved here if it is replaced by a diff
  526. from another buffer.  This alist has the form:
  527. \((num (buff-object . diff) (buff-object . diff) (buff-object . diff)) ...),
  528. where some buffer-objects may be missing.")
  529.  
  530.  
  531. ;; Highlighting
  532. ;;(defvar ediff-before-flag-bol (if ediff-emacs-p "->>\n" (make-glyph "->>\n"))
  533. (defvar ediff-before-flag-bol (if ediff-xemacs-p (make-glyph "->>") "->>")
  534.   "*Flag placed above the highlighted block of differences. 
  535. Must end with newline.")
  536. ;;(defvar ediff-after-flag-eol  (if ediff-emacs-p "<<-\n" (make-glyph "<<-"))
  537. (defvar ediff-after-flag-eol  (if ediff-xemacs-p (make-glyph "<<-") "<<-")
  538.   "*Flag placed below the highlighted block of differences.
  539. Must end with newline.")
  540.  
  541. (defvar ediff-before-flag-mol (if ediff-xemacs-p (make-glyph "->>") "->>")
  542.   "*Like ediff-before-flag, used when a difference starts in mid-line.")
  543. (defvar ediff-after-flag-mol  (if ediff-xemacs-p (make-glyph "<<-") "<<-")
  544.   "*Like ediff-after-flag, used when a difference starts in mid-line.")
  545.  
  546.   
  547. (ediff-defvar-local ediff-use-faces t 
  548.   "If t, differences are highlighted using faces, if device supports faces.
  549. If nil, differences are highlighted using ASCII flags, ediff-before-flag
  550. and ediff-after-flag.  On a non-window system, differences are always
  551. highlighted using ASCII flags.
  552. This variable can be set either in .emacs or toggled interactively.
  553. Use `setq-default' if setting it in .emacs")
  554.  
  555. ;; this indicates that diff regions are word-size, so fine diffs are
  556. ;; permanently nixed; used in ediff-windows-wordwise and ediff-regions-wordwise
  557. (ediff-defvar-local ediff-word-mode nil "")
  558. ;; Name of the job (ediff-files, ediff-windows, etc.)
  559. (ediff-defvar-local ediff-job-name nil "")
  560.  
  561. ;; Narrowing and ediff-region/windows support
  562. ;; This is a list (overlay-A overlay-B overlay-C)
  563. ;; If set, Ediff compares only those parts of buffers A/B/C that lie within
  564. ;; the bounds of these overlays.
  565. (ediff-defvar-local ediff-narrow-bounds nil "")
  566.  
  567. ;; List (overlay-A overlay-B overlay-C), where each overlay spans the
  568. ;; entire corresponding buffer.
  569. (ediff-defvar-local ediff-wide-bounds nil "")
  570.  
  571. ;; Current visibility boundaries in buffers A, B, and C.
  572. ;; This is also a list of overlays. When the user toggles narrow/widen,
  573. ;; this list changes from ediff-wide-bounds to ediff-narrow-bounds.
  574. ;; and back.
  575. (ediff-defvar-local ediff-visible-bounds nil "")
  576.  
  577. (ediff-defvar-local ediff-start-narrowed t
  578.   "Non-nil means start narrowed, if doing ediff-windows-* or ediff-regions-*")
  579. (ediff-defvar-local ediff-quit-widened t
  580.   "*Non-nil means: when finished, Ediff widens buffers A/B.
  581. Actually, Ediff restores the scope of visibility that existed at startup.")
  582. (defvar ediff-keep-variants t
  583.   "*Nil means that non-modified variant buffers should be removed after some
  584. interrogation.
  585. Supplying a prefix argument to the quit command `q' temporarily reverses the
  586. meaning of this variable.")
  587.  
  588. (ediff-defvar-local ediff-highlight-all-diffs t
  589.   "If nil, only the selected differences are highlighted.
  590. This variable can be set either in .emacs or toggled interactively, using
  591. ediff-toggle-hilit. Use `setq-default' to set it.") 
  592.  
  593. ;; A var local to each control panel buffer.  Indicates highlighting style
  594. ;; in effect for this buffer: `face', `ascii', nil -- temporarily
  595. ;; unhighlighted, `off' -- turned off \(on a dumb terminal only\).
  596. (ediff-defvar-local ediff-highlighting-style nil "")
  597.  
  598.   
  599. ;; The suffix of the control buffer name.
  600. (ediff-defvar-local ediff-control-buffer-suffix nil "")
  601. ;; Same as ediff-control-buffer-suffix, but without <,>. 
  602. ;; It's a number rather than string.
  603. (ediff-defvar-local ediff-control-buffer-number nil "")
  604.  
  605.  
  606. ;; The original values of ediff-protected-variables for buffer A
  607. (ediff-defvar-local ediff-buffer-values-orig-A nil "")
  608. ;; The original values of ediff-protected-variables for buffer B
  609. (ediff-defvar-local ediff-buffer-values-orig-B nil "")
  610. ;; The original values of ediff-protected-variables for buffer C
  611. (ediff-defvar-local ediff-buffer-values-orig-C nil "")
  612. ;; The original values of ediff-protected-variables for buffer Ancestor
  613. (ediff-defvar-local ediff-buffer-values-orig-Ancestor nil "")
  614. ;; Buffer-local variables to be saved then restored during Ediff sessions
  615. ;; Buffer-local variables to be saved then restored during Ediff sessions
  616. (defconst ediff-protected-variables '(buffer-read-only 
  617. ;;;                      synchronize-minibuffers
  618.                       mode-line-format))
  619.  
  620. ;; Vector of differences between the variants.  Each difference is
  621. ;; represented by a vector of two overlays plus a vector of fine diffs,
  622. ;; plus a no-fine-diffs flag.  The first overlay spans the
  623. ;; difference region in the A buffer and the second overlays the diff in
  624. ;; the B buffer. If a difference section is empty, the corresponding
  625. ;; overlay's endpoints coincide.
  626. ;;
  627. ;; The precise form of a difference vector for one buffer is:
  628. ;; [diff diff diff ...]
  629. ;; where each diff has the form:
  630. ;; [diff-overlay fine-diff-vector no-fine-diffs-flag state-of-difference]
  631. ;; fine-diff-vector is a vector [fine-diff-overlay fine-diff-overlay ...]
  632. ;; no-fine-diffs-flag says if there are fine differences.
  633. ;; state-of-difference is A, B, C, or nil, indicating which buffer is
  634. ;; different from the other two (used only in 3-way jobs.
  635. (ediff-defvar-local ediff-difference-vector-A nil "")
  636. (ediff-defvar-local ediff-difference-vector-B nil "")
  637. (ediff-defvar-local ediff-difference-vector-C nil "")
  638. (ediff-defvar-local ediff-difference-vector-Ancestor nil "")
  639.  
  640. ;; [ status status status ...]
  641. ;; Each status: [state-of-merge state-of-ancestor]
  642. ;; state-of-merge is default-A, default-B, prefer-A, or prefer-B. It
  643. ;; indicates the way a diff region was created in buffer C.
  644. ;; state-of-ancestor says if the corresponding region in ancestor buffer is
  645. ;; empty.
  646. (ediff-defvar-local ediff-state-of-merge nil "")
  647.  
  648. ;; The difference that is currently selected.
  649. (ediff-defvar-local ediff-current-difference -1 "")
  650. ;; Number of differences found.
  651. (ediff-defvar-local ediff-number-of-differences nil "")
  652.   
  653. ;; Buffer containing the output of diff, which is used by Ediff to step
  654. ;; through files.
  655. (ediff-defvar-local ediff-diff-buffer nil "")
  656. ;; Like ediff-diff-buffer, but contains context diff. It is not used by
  657. ;; Ediff, but it is saved in a file, if user requests so.
  658. (ediff-defvar-local ediff-custom-diff-buffer nil "")
  659. ;; Buffer used for diff-style fine differences between regions.
  660. (ediff-defvar-local ediff-fine-diff-buffer nil "")
  661. ;; Temporary buffer used for computing fine differences.
  662. (defconst ediff-tmp-buffer " *ediff-tmp*" "")
  663. ;; Buffer used for messages
  664. (defconst ediff-msg-buffer " *ediff-message*" "")
  665. ;; Buffer containing the output of diff when diff returns errors.
  666. (ediff-defvar-local ediff-error-buffer nil "")
  667. ;; Buffer to display debug info
  668. (ediff-defvar-local ediff-debug-buffer "*ediff-debug*" "")
  669.  
  670. ;; List of ediff control panels associated with each buffer A/B/C/Ancestor.
  671. ;; Not used any more, but may be needed in the future.
  672. (ediff-defvar-local ediff-this-buffer-ediff-sessions  nil "")
  673.  
  674. ;; to be deleted in due time
  675. ;; List of difference overlays disturbed by working with the current diff.
  676. (defvar ediff-disturbed-overlays nil "")
  677.   
  678. ;; Priority of non-selected overlays.
  679. (defvar ediff-shadow-overlay-priority  100 "")
  680.  
  681. (defvar ediff-version-control-package 'vc
  682.   "Version control package used.
  683. Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el. The
  684. standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el. However, some
  685. people find the other two packages more convenient. Set this variable to the
  686. appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire.")
  687.  
  688.  
  689. (if ediff-xemacs-p
  690.     (progn
  691.       (fset 'ediff-read-event (symbol-function 'next-command-event))
  692.       (fset 'ediff-overlayp (symbol-function 'extentp))
  693.       (fset 'ediff-make-overlay (symbol-function 'make-extent))
  694.       (fset 'ediff-delete-overlay (symbol-function 'delete-extent)))
  695.   (fset 'ediff-read-event (symbol-function 'read-event))
  696.   (fset 'ediff-overlayp (symbol-function 'overlayp))
  697.   (fset 'ediff-overlayp (symbol-function 'overlayp))
  698.   (fset 'ediff-make-overlay (symbol-function 'make-overlay))
  699.   (fset 'ediff-delete-overlay (symbol-function 'delete-overlay)))
  700.   
  701. ;; Check the current version against the major and minor version numbers
  702. ;; using op: cur-vers op major.minor If emacs-major-version or
  703. ;; emacs-minor-version are not defined, we assume that the current version
  704. ;; is hopelessly outdated.  We assume that emacs-major-version and
  705. ;; emacs-minor-version are defined.  Otherwise, for Emacs/XEmacs 19, if the
  706. ;; current minor version is < 10 (xemacs) or < 23 (emacs) the return value
  707. ;; will be nil (when op is =, >, or >=) and t (when op is <, <=), which may be
  708. ;; incorrect. However, this gives correct result in our cases, since we are
  709. ;; testing for sufficiently high Emacs versions.
  710. (defun ediff-check-version (op major minor &optional type-of-emacs)
  711.   (if (and (boundp 'emacs-major-version) (boundp 'emacs-minor-version))
  712.       (and (cond ((eq type-of-emacs 'xemacs) ediff-xemacs-p)
  713.          ((eq type-of-emacs 'emacs) ediff-emacs-p)
  714.          (t t))
  715.        (cond ((eq op '=) (and (= emacs-minor-version minor)
  716.                   (= emacs-major-version major)))
  717.          ((memq op '(> >= < <=))
  718.           (and (or (funcall op emacs-major-version major)
  719.                (= emacs-major-version major))
  720.                (if (= emacs-major-version major)
  721.                (funcall op emacs-minor-version minor)
  722.              t)))
  723.          (t
  724.           (error "%S: Invalid op in ediff-check-version" op))))
  725.     (cond ((memq op '(= > >=)) nil)
  726.       ((memq op '(< <=)) t))))
  727.   
  728.   
  729. ;;;; warn if it is a wrong version of emacs
  730. ;;(if (or (ediff-check-version '< 19 29 'emacs)
  731. ;;    (ediff-check-version '< 19 12 'xemacs))
  732. ;;    (progn
  733. ;;      (with-output-to-temp-buffer ediff-msg-buffer
  734. ;;    (switch-to-buffer ediff-msg-buffer)
  735. ;;    (insert
  736. ;;     (format "
  737. ;;
  738. ;;This version of Ediff requires 
  739. ;;
  740. ;;\t Emacs 19.29 and higher
  741. ;;\t OR
  742. ;;\t XEmacs 19.12 and higher
  743. ;;
  744. ;;It is unlikely to work under Emacs version %s
  745. ;;that you are using... " emacs-version))
  746. ;;    (if noninteractive
  747. ;;        ()
  748. ;;      (beep 1)
  749. ;;      (beep 1)
  750. ;;      (insert "\n\nType any key to continue...")
  751. ;;      (ediff-read-event)))
  752. ;;      (kill-buffer ediff-msg-buffer)))
  753.  
  754. ;; A fix for NeXT Step
  755. ;; Should probably be eliminated in later versions.
  756. (if (and (ediff-window-display-p) (eq (ediff-device-type) 'ns))
  757.     (progn
  758.       (fset 'x-display-color-p (symbol-function 'ns-display-color-p))
  759.       (fset 'x-color-defined-p (symbol-function 'ns-color-defined-p))
  760.       (fset 'x-display-pixel-height (symbol-function 'ns-display-pixel-height))
  761.       (fset 'x-display-pixel-width (symbol-function 'ns-display-pixel-width))
  762.       ))
  763.  
  764.  
  765. (defsubst ediff-color-display-p ()
  766.   (if ediff-emacs-p
  767.       (x-display-color-p)
  768.     (eq (device-class (selected-device)) 'color)))
  769.  
  770.   
  771. (if (ediff-has-face-support-p)
  772.     (if ediff-xemacs-p
  773.     (progn
  774.       (fset 'ediff-valid-color-p (symbol-function 'valid-color-name-p))
  775.       (fset 'ediff-get-face (symbol-function 'get-face)))
  776.       ;; Temporary fix for OS/2 port of Emacs
  777.       ;; pm-win.el in PM-Emacs should be fixed.
  778.       (if (eq (ediff-device-type) 'pm)
  779.       (fset 'ediff-valid-color-p 
  780.         (function (lambda (color) (assoc color pm-color-alist))))
  781.     (fset 'ediff-valid-color-p (symbol-function 'x-color-defined-p)))
  782.       (fset 'ediff-get-face (symbol-function 'internal-get-face))))
  783.  
  784. (if (ediff-window-display-p)
  785.     (if ediff-xemacs-p
  786.     (progn
  787.       (fset 'ediff-display-pixel-width
  788.         (symbol-function 'device-pixel-width))
  789.       (fset 'ediff-display-pixel-height
  790.         (symbol-function 'device-pixel-height)))
  791.       (fset 'ediff-display-pixel-width 
  792.         (symbol-function 'x-display-pixel-width))
  793.       (fset 'ediff-display-pixel-height
  794.         (symbol-function 'x-display-pixel-height))))
  795.       
  796.  
  797. (defun ediff-make-current-diff-overlay (type)
  798.   (if (ediff-has-face-support-p)
  799.       (let ((overlay (intern (format "ediff-current-diff-overlay-%S" type)))
  800.         (buffer (ediff-get-buffer type))
  801.         (face (face-name
  802.            (symbol-value
  803.             (intern (format "ediff-current-diff-face-%S" type))))))
  804.     (set overlay
  805.          (ediff-make-bullet-proof-overlay (point-max) (point-max) buffer))
  806.     (ediff-set-overlay-face (symbol-value overlay) face)
  807.     (ediff-overlay-put (symbol-value overlay) 'ediff ediff-control-buffer))
  808.     ))
  809.  
  810. (defun ediff-set-overlay-face (extent face)
  811.   (ediff-overlay-put extent 'face face)
  812.   (ediff-overlay-put extent 'help-echo 'ediff-region-help-echo))
  813.  
  814. ;; This does nothing in Emacs, since overlays there have no help-echo property
  815. (defun ediff-region-help-echo (extent)
  816.   (let ((is-current (ediff-overlay-get extent 'ediff))
  817.     (face (ediff-overlay-get extent 'face))
  818.     (diff-num (ediff-overlay-get extent 'ediff-diff-num))
  819.     face-help)
  820.  
  821.     ;; This happens only for refinement overlays
  822.     (setq face-help (and face (get face 'ediff-help-echo)))
  823.  
  824.     (cond ((and is-current diff-num) ; current diff region
  825.        (format "Difference region %S -- current" (1+ diff-num)))
  826.       (face-help) ; refinement of current diff region
  827.       (diff-num ; non-current
  828.        (format "Difference region %S -- non-current" (1+ diff-num)))
  829.       (t ""))   ; none
  830.     ))
  831.  
  832. (defun ediff-set-face (ground face color)
  833.   "Set face foreground/background."
  834.   (if (ediff-has-face-support-p)
  835.       (if (ediff-valid-color-p color)
  836.       (if (eq ground 'foreground)
  837.           (set-face-foreground face color)
  838.         (set-face-background face color))
  839.     (cond ((memq face
  840.              '(ediff-current-diff-face-A
  841.                ediff-current-diff-face-B
  842.                ediff-current-diff-face-C
  843.                ediff-current-diff-face-Ancestor))
  844.            (copy-face 'highlight face))
  845.           ((memq face
  846.              '(ediff-fine-diff-face-A
  847.                ediff-fine-diff-face-B
  848.                ediff-fine-diff-face-C
  849.                ediff-fine-diff-face-Ancestor))
  850.            (copy-face 'secondary-selection face)
  851.            (set-face-underline-p face t))
  852.           ((memq face
  853.              '(ediff-even-diff-face-A
  854.                ediff-odd-diff-face-A 
  855.                ediff-even-diff-face-B ediff-odd-diff-face-B
  856.                ediff-even-diff-face-C ediff-odd-diff-face-C
  857.                ediff-even-diff-face-Ancestor
  858.                ediff-odd-diff-face-Ancestor))
  859.            (copy-face 'secondary-selection face))))
  860.     ))
  861.  
  862. (defun ediff-hide-face (face)
  863.   (if (and (ediff-has-face-support-p) ediff-emacs-p)
  864.       (add-to-list 'facemenu-unlisted-faces face)))
  865.       
  866. (defvar ediff-current-diff-face-A
  867.   (if (ediff-has-face-support-p)
  868.       (progn
  869.     (make-face 'ediff-current-diff-face-A)
  870.     (ediff-hide-face 'ediff-current-diff-face-A)
  871.     (or (face-differs-from-default-p 'ediff-current-diff-face-A)
  872.         (cond ((ediff-color-display-p)
  873.            (ediff-set-face
  874.             'foreground 'ediff-current-diff-face-A "firebrick")
  875.            (ediff-set-face
  876.             'background 'ediff-current-diff-face-A "pale green"))
  877.           (t
  878.            (if ediff-xemacs-p
  879.                (copy-face 'modeline 'ediff-current-diff-face-A)
  880.              (copy-face 'highlight 'ediff-current-diff-face-A))
  881.            )))
  882.     'ediff-current-diff-face-A))
  883.   "Face for highlighting the selected difference in buffer A.")
  884.  
  885. (defvar ediff-current-diff-face-B
  886.   (if (ediff-has-face-support-p)
  887.       (progn
  888.     (make-face 'ediff-current-diff-face-B)
  889.     (ediff-hide-face 'ediff-current-diff-face-B)
  890.     (or (face-differs-from-default-p 'ediff-current-diff-face-B)
  891.         (cond ((ediff-color-display-p)
  892.            (ediff-set-face
  893.             'foreground 'ediff-current-diff-face-B "DarkOrchid")
  894.            (ediff-set-face
  895.             'background 'ediff-current-diff-face-B "Yellow"))
  896.           (t 
  897.            (if ediff-xemacs-p
  898.                (copy-face 'modeline 'ediff-current-diff-face-B)
  899.              (copy-face 'highlight 'ediff-current-diff-face-B))
  900.            )))
  901.     'ediff-current-diff-face-B))
  902.   "Face for highlighting the selected difference in buffer B.")
  903.     
  904.  
  905. (defvar ediff-current-diff-face-C
  906.   (if (ediff-has-face-support-p)
  907.       (progn
  908.     (make-face 'ediff-current-diff-face-C)
  909.     (ediff-hide-face 'ediff-current-diff-face-C)
  910.     (or (face-differs-from-default-p 'ediff-current-diff-face-C)
  911.         (cond ((ediff-color-display-p)
  912.            (ediff-set-face
  913.             'foreground 'ediff-current-diff-face-C "Navy")
  914.            (ediff-set-face
  915.             'background 'ediff-current-diff-face-C "Pink"))
  916.           (t 
  917.            (if ediff-xemacs-p
  918.                (copy-face 'modeline 'ediff-current-diff-face-C)
  919.              (copy-face 'highlight 'ediff-current-diff-face-C))
  920.            )))
  921.     'ediff-current-diff-face-C))
  922.   "Face for highlighting the selected difference in buffer C.")
  923.  
  924. (defvar ediff-current-diff-face-Ancestor
  925.   (if (ediff-has-face-support-p)
  926.       (progn
  927.     (make-face 'ediff-current-diff-face-Ancestor)
  928.     (ediff-hide-face 'ediff-current-diff-face-Ancestor)
  929.     (or (face-differs-from-default-p 'ediff-current-diff-face-Ancestor)
  930.         (copy-face 
  931.          'ediff-current-diff-face-C 'ediff-current-diff-face-Ancestor))))
  932.   "Face for highlighting the selected difference in the ancestor buffer.")
  933.  
  934. (defvar ediff-fine-diff-face-A
  935.   (if (ediff-has-face-support-p)
  936.       (progn
  937.     (make-face 'ediff-fine-diff-face-A)
  938.     (ediff-hide-face 'ediff-fine-diff-face-A)
  939.     (or (face-differs-from-default-p 'ediff-fine-diff-face-A)
  940.         (cond ((ediff-color-display-p)
  941.            (ediff-set-face 'foreground 'ediff-fine-diff-face-A
  942.                    "Navy")
  943.            (ediff-set-face 'background 'ediff-fine-diff-face-A
  944.                    "sky blue"))
  945.           (t (set-face-underline-p 'ediff-fine-diff-face-A t))))
  946.     'ediff-fine-diff-face-A))
  947.   "Face for highlighting the refinement of the selected diff in buffer A.")
  948.  
  949. (defvar ediff-fine-diff-face-B
  950.   (if (ediff-has-face-support-p)
  951.       (progn
  952.     (make-face 'ediff-fine-diff-face-B)
  953.     (ediff-hide-face 'ediff-fine-diff-face-B)
  954.     (or (face-differs-from-default-p 'ediff-fine-diff-face-B)
  955.         (cond ((ediff-color-display-p)
  956.            (ediff-set-face 'foreground 'ediff-fine-diff-face-B "Black")
  957.            (ediff-set-face 'background 'ediff-fine-diff-face-B "cyan"))
  958.           (t (set-face-underline-p 'ediff-fine-diff-face-B t))))
  959.     'ediff-fine-diff-face-B))
  960.   "Face for highlighting the refinement of the selected diff in buffer B.")
  961.     
  962. (defvar ediff-fine-diff-face-C
  963.   (if (ediff-has-face-support-p)
  964.       (progn
  965.     (make-face 'ediff-fine-diff-face-C)
  966.     (ediff-hide-face 'ediff-fine-diff-face-C)
  967.     (or (face-differs-from-default-p 'ediff-fine-diff-face-C)
  968.         (cond ((ediff-color-display-p)
  969.            (ediff-set-face 'foreground 'ediff-fine-diff-face-C "black")
  970.            (ediff-set-face
  971.             'background 'ediff-fine-diff-face-C "Turquoise"))
  972.           (t (set-face-underline-p 'ediff-fine-diff-face-C t))))
  973.     'ediff-fine-diff-face-C))
  974.   "Face for highlighting the refinement of the selected diff in buffer C.")
  975.  
  976. (defvar ediff-fine-diff-face-Ancestor
  977.   (if (ediff-has-face-support-p)
  978.       (progn
  979.     (make-face 'ediff-fine-diff-face-Ancestor)
  980.     (ediff-hide-face 'ediff-fine-diff-face-Ancestor)
  981.     (or (face-differs-from-default-p 'ediff-fine-diff-face-Ancestor)
  982.         (copy-face
  983.          'ediff-fine-diff-face-C 'ediff-fine-diff-face-Ancestor))))
  984.   "Face highlighting refinements of the selected diff in ancestor buffer.
  985. Presently, this is not used, as difference regions are not refined in the
  986. ancestor buffer.")
  987.     
  988. (defvar ediff-even-diff-face-A
  989.   (if (ediff-has-face-support-p)
  990.       (progn
  991.     (make-face 'ediff-even-diff-face-A)
  992.     (ediff-hide-face 'ediff-even-diff-face-A)
  993.     (or (face-differs-from-default-p 'ediff-even-diff-face-A)
  994.         (cond ((ediff-color-display-p)
  995.            (ediff-set-face
  996.             'foreground 'ediff-even-diff-face-A "black")
  997.            (ediff-set-face
  998.             'background 'ediff-even-diff-face-A "light grey"))
  999.           (t 
  1000.            (copy-face 'italic 'ediff-even-diff-face-A))))
  1001.     'ediff-even-diff-face-A))
  1002.   "Face used to highlight even-numbered differences in buffer A.")
  1003.       
  1004. (defvar ediff-even-diff-face-B
  1005.   (if (ediff-has-face-support-p)
  1006.       (progn
  1007.     (make-face 'ediff-even-diff-face-B)
  1008.     (ediff-hide-face 'ediff-even-diff-face-B)
  1009.     (or (face-differs-from-default-p 'ediff-even-diff-face-B)
  1010.         (cond ((ediff-color-display-p)
  1011.            (ediff-set-face
  1012.             'foreground 'ediff-even-diff-face-B "White")
  1013.            (ediff-set-face
  1014.             'background 'ediff-even-diff-face-B "Gray"))
  1015.           (t 
  1016.            (copy-face 'italic 'ediff-even-diff-face-B))))
  1017.     'ediff-even-diff-face-B))
  1018.   "Face used to highlight even-numbered differences in buffer B.")
  1019.     
  1020. (defvar ediff-even-diff-face-C
  1021.   (if (ediff-has-face-support-p)
  1022.       (progn
  1023.     (make-face 'ediff-even-diff-face-C)
  1024.     (ediff-hide-face 'ediff-even-diff-face-C)
  1025.     (or (face-differs-from-default-p 'ediff-even-diff-face-C)
  1026.         (copy-face 'ediff-even-diff-face-A 'ediff-even-diff-face-C))
  1027.     'ediff-even-diff-face-C))
  1028.   "Face used to highlight even-numbered differences in buffer C.")
  1029.  
  1030. (defvar ediff-even-diff-face-Ancestor
  1031.   (if (ediff-has-face-support-p)
  1032.       (progn
  1033.     (make-face 'ediff-even-diff-face-Ancestor)
  1034.     (ediff-hide-face 'ediff-even-diff-face-Ancestor)
  1035.     (or (face-differs-from-default-p 'ediff-even-diff-face-Ancestor)
  1036.         (copy-face 'ediff-even-diff-face-C 'ediff-even-diff-face-Ancestor))
  1037.     'ediff-even-diff-face-Ancestor))
  1038.   "Face highlighting even-numbered differences in the ancestor buffer.")
  1039.   
  1040. (defvar ediff-odd-diff-face-A
  1041.   (if (ediff-has-face-support-p)
  1042.       (progn
  1043.     (make-face 'ediff-odd-diff-face-A)
  1044.     (ediff-hide-face 'ediff-odd-diff-face-A)
  1045.     (or (face-differs-from-default-p 'ediff-odd-diff-face-A)
  1046.         (cond ((ediff-color-display-p)
  1047.            (ediff-set-face
  1048.             'foreground 'ediff-odd-diff-face-A "White")
  1049.            (ediff-set-face
  1050.             'background 'ediff-odd-diff-face-A "Gray"))
  1051.           (t 
  1052.            (copy-face 'italic 'ediff-odd-diff-face-A))))
  1053.     'ediff-odd-diff-face-A))
  1054.   "Face used to highlight odd-numbered differences in buffer A.")
  1055.       
  1056. (defvar ediff-odd-diff-face-B
  1057.   (if (ediff-has-face-support-p)
  1058.       (progn
  1059.     (make-face 'ediff-odd-diff-face-B)
  1060.     (ediff-hide-face 'ediff-odd-diff-face-B)
  1061.     (or (face-differs-from-default-p 'ediff-odd-diff-face-B)
  1062.         (cond ((ediff-color-display-p)
  1063.            (ediff-set-face
  1064.             'foreground 'ediff-odd-diff-face-B "Black")
  1065.            (ediff-set-face
  1066.             'background 'ediff-odd-diff-face-B "light grey"))
  1067.           (t 
  1068.            (copy-face 'italic 'ediff-odd-diff-face-B))))
  1069.     'ediff-odd-diff-face-B))
  1070.   "Face used to highlight odd-numbered differences in buffer B.")
  1071.     
  1072. (defvar ediff-odd-diff-face-C
  1073.   (if (ediff-has-face-support-p)
  1074.       (progn
  1075.     (make-face 'ediff-odd-diff-face-C)
  1076.     (ediff-hide-face 'ediff-odd-diff-face-C)
  1077.     (or (face-differs-from-default-p 'ediff-odd-diff-face-C)
  1078.         (copy-face 'ediff-odd-diff-face-A 'ediff-odd-diff-face-C))
  1079.     'ediff-odd-diff-face-C))
  1080.   "Face used to highlight odd-numbered differences in buffer C.")
  1081.  
  1082. (defvar ediff-odd-diff-face-Ancestor 
  1083.   (if (ediff-has-face-support-p)
  1084.       (progn
  1085.     (make-face 'ediff-odd-diff-face-Ancestor)
  1086.     (ediff-hide-face 'ediff-odd-diff-face-Ancestor)
  1087.     (or (face-differs-from-default-p 'ediff-odd-diff-face-Ancestor)
  1088.         (copy-face 'ediff-odd-diff-face-C 'ediff-odd-diff-face-Ancestor))
  1089.     'ediff-odd-diff-face-Ancestor))
  1090.   "Face used to highlight even-numbered differences in the ancestor buffer.")
  1091.  
  1092. ;; Help echo
  1093. (put 'ediff-fine-diff-face-A 'ediff-help-echo
  1094.      "A `refinement' of the current difference region")
  1095. (put 'ediff-fine-diff-face-B 'ediff-help-echo
  1096.      "A `refinement' of the current difference region")
  1097. (put 'ediff-fine-diff-face-C 'ediff-help-echo
  1098.      "A `refinement' of the current difference region")
  1099. (put 'ediff-fine-diff-face-Ancestor 'ediff-help-echo
  1100.      "A `refinement' of the current difference region")
  1101.  
  1102.  
  1103. ;;; Overlays
  1104.  
  1105. (ediff-defvar-local ediff-current-diff-overlay-A nil
  1106.   "Overlay for the current difference region in buffer A.")
  1107. (ediff-defvar-local ediff-current-diff-overlay-B nil
  1108.   "Overlay for the current difference region in buffer B.")
  1109. (ediff-defvar-local ediff-current-diff-overlay-C nil
  1110.   "Overlay for the current difference region in buffer C.")
  1111. (ediff-defvar-local ediff-current-diff-overlay-Ancestor nil
  1112.   "Overlay for the current difference region in the ancestor buffer.")
  1113.   
  1114. ;; Compute priority of ediff overlay.
  1115. (defun ediff-highest-priority (start end buffer)
  1116.   (let ((pos (max 1 (1- start)))
  1117.     ovr-list)
  1118.     (if ediff-xemacs-p
  1119.     (1+ ediff-shadow-overlay-priority)
  1120.       (ediff-eval-in-buffer buffer
  1121.     (while (< pos (min (point-max) (1+ end)))
  1122.       (setq ovr-list (append (overlays-at pos) ovr-list))
  1123.       (setq pos (next-overlay-change pos)))
  1124.     (1+ (apply '+
  1125.            (mapcar (function
  1126.                 (lambda (ovr)
  1127.                   (if ovr
  1128.                   (or (ediff-overlay-get ovr 'priority) 0)
  1129.                 0)))
  1130.                ovr-list)
  1131.            ))
  1132.     ))))
  1133.   
  1134.     
  1135. (defvar ediff-toggle-read-only-function nil
  1136.   "*Specifies the function to be used to toggle read-only.
  1137. If nil, Ediff tries to deduce the function from the binding of C-x C-q.
  1138. Normally, this is the `toggle-read-only' function, but, if version
  1139. control is used, it could be `vc-toggle-read-only' or `rcs-toggle-read-only'.")
  1140.  
  1141.  
  1142. ;;; Misc
  1143.  
  1144. ;; if nil, this silences some messages
  1145. (defconst ediff-verbose-p t)
  1146.   
  1147. (defvar ediff-no-emacs-help-in-control-buffer nil
  1148.   "*Non-nil means C-h should not invoke Emacs help in control buffer.
  1149. Instead, C-h jumps to previous difference.")
  1150.   
  1151. (defvar ediff-temp-file-prefix
  1152.   (let ((env (or (getenv "TMPDIR")
  1153.          (getenv "TMP")
  1154.          (getenv "TEMP")))
  1155.     d)
  1156.     (setq d (if (and env (> (length env) 0))
  1157.         env
  1158.           (cond ((memq system-type '(vax-vms axp-vms)) "SYS$SCRATCH:")
  1159.              ((eq system-type 'ms-dos) "c:/")
  1160.              (t "/tmp"))))
  1161.     ;; The following is to make sure we get something to which we can
  1162.     ;; add directory levels on VMS.
  1163.     (setq d (file-name-as-directory (directory-file-name d)))
  1164.     )
  1165.   "*Prefix to put on Ediff temporary file names.
  1166. Do not start with `~/' or `~user-name/'.")  
  1167.  
  1168. (defvar ediff-temp-file-mode 384    ; u=rw only
  1169.   "*Mode for Ediff temporary files.")
  1170.   
  1171. ;; Metacharacters that have to be protected from the shell when executing
  1172. ;; a diff/diff3 command.
  1173. (defvar ediff-metachars "[ \t\n!\"#$&'()*;<=>?[\\^`{|~]"
  1174.   "Characters that must be quoted with \\ when used in a shell command line.
  1175. More precisely, a regexp to match any one such character.")
  1176.  
  1177. ;; needed to simulate frame-char-width in XEmacs.
  1178. (defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H")))
  1179.  
  1180.   
  1181. (ediff-defvar-local ediff-temp-file-A nil
  1182.   "Temporary file used for refining difference regions in buffer A.")
  1183. (ediff-defvar-local ediff-temp-file-B nil
  1184.   "Temporary file used for refining difference regions in buffer B.")
  1185. (ediff-defvar-local ediff-temp-file-C nil
  1186.   "Temporary file used for refining difference regions in buffer C.")
  1187.  
  1188. ;;; In-line functions
  1189.  
  1190. (defsubst ediff-file-remote-p (file-name)
  1191.   (if (fboundp ediff-ange-ftp-ftp-name)
  1192.       (funcall ediff-ange-ftp-ftp-name file-name)))
  1193.  
  1194.     
  1195. (defsubst ediff-frame-unsplittable-p (frame)
  1196.   (cdr (assq 'unsplittable (frame-parameters frame))))
  1197.  
  1198. (defsubst ediff-get-next-window (wind prev-wind)
  1199.   (or (window-live-p wind)
  1200.       (setq wind (if prev-wind
  1201.              (next-window wind)
  1202.            (selected-window)))))
  1203.  
  1204.  
  1205. (defsubst ediff-kill-buffer-carefully (buf)
  1206.   "Kill buffer BUF if it exists."
  1207.   (if (ediff-buffer-live-p buf)
  1208.       (kill-buffer (get-buffer buf))))
  1209.       
  1210.  
  1211. (defsubst ediff-highlight-diff (n)
  1212.   "Put face on diff N.  Invoked for X displays only."
  1213.   (ediff-highlight-diff-in-one-buffer n 'A)
  1214.   (ediff-highlight-diff-in-one-buffer n 'B)
  1215.   (ediff-highlight-diff-in-one-buffer n 'C)
  1216.   (ediff-highlight-diff-in-one-buffer n 'Ancestor)
  1217.   )
  1218.  
  1219.  
  1220. (defsubst ediff-unhighlight-diff ()
  1221.   "Remove overlays from buffers A, B, and C."
  1222.   (ediff-unhighlight-diff-in-one-buffer 'A)
  1223.   (ediff-unhighlight-diff-in-one-buffer 'B)
  1224.   (ediff-unhighlight-diff-in-one-buffer 'C)
  1225.   (ediff-unhighlight-diff-in-one-buffer 'Ancestor)
  1226.   )
  1227.     
  1228. ;; delete highlighting overlays, restore faces to their original form
  1229. (defsubst ediff-unhighlight-diffs-totally ()
  1230.   (ediff-unhighlight-diffs-totally-in-one-buffer 'A)
  1231.   (ediff-unhighlight-diffs-totally-in-one-buffer 'B)
  1232.   (ediff-unhighlight-diffs-totally-in-one-buffer 'C)
  1233.   (ediff-unhighlight-diffs-totally-in-one-buffer 'Ancestor)
  1234.   )
  1235.  
  1236. (defsubst ediff-background-face (buf-type dif-num)
  1237.   ;; The value of dif-num is always 1- the one that user sees.
  1238.   ;; This is why even face is used when dif-num is odd.
  1239.   (intern (format (if (ediff-odd-p dif-num)
  1240.               "ediff-even-diff-face-%S"
  1241.             "ediff-odd-diff-face-%S")
  1242.           buf-type)))
  1243.     
  1244.       
  1245. ;; arg is a record for a given diff in a difference vector
  1246. ;; this record is itself a vector
  1247. (defsubst ediff-clear-fine-diff-vector (diff-record)
  1248.   (if diff-record
  1249.       (mapcar 'ediff-delete-overlay
  1250.           (ediff-get-fine-diff-vector-from-diff-record diff-record))))
  1251.           
  1252. (defsubst ediff-clear-fine-differences-in-one-buffer (n buf-type)
  1253.   (ediff-clear-fine-diff-vector (ediff-get-difference n buf-type))
  1254.   (ediff-set-fine-diff-vector n buf-type nil))
  1255.   
  1256. (defsubst ediff-clear-fine-differences (n)
  1257.   (ediff-clear-fine-differences-in-one-buffer n 'A)
  1258.   (ediff-clear-fine-differences-in-one-buffer n 'B)
  1259.   (if ediff-3way-job
  1260.       (ediff-clear-fine-differences-in-one-buffer n 'C)))
  1261.       
  1262.  
  1263. (defsubst ediff-convert-fine-diffs-to-overlays (diff-list region-num)
  1264.   (ediff-set-fine-overlays-in-one-buffer 'A diff-list region-num)
  1265.   (ediff-set-fine-overlays-in-one-buffer 'B diff-list region-num)
  1266.   (if ediff-3way-job
  1267.       (ediff-set-fine-overlays-in-one-buffer 'C diff-list region-num)
  1268.     ))
  1269.   
  1270. (defsubst ediff-mouse-event-p (event)
  1271.   (if ediff-xemacs-p
  1272.       (button-event-p event)
  1273.     (string-match "mouse" (format "%S" (event-basic-type event)))
  1274.     ))
  1275.  
  1276.  
  1277. (defsubst ediff-key-press-event-p (event)
  1278.   (if ediff-xemacs-p
  1279.       (key-press-event-p event)
  1280.     (or (char-or-string-p event) (symbolp event))))
  1281.  
  1282. (defun ediff-event-point (event)
  1283.   (cond ((ediff-mouse-event-p event)
  1284.      (if ediff-xemacs-p
  1285.          (event-point event)
  1286.        (posn-point (event-start event))))
  1287.     ((ediff-key-press-event-p event)
  1288.      (point))
  1289.     (t (error))))
  1290.  
  1291. (defun ediff-event-buffer (event)
  1292.   (cond ((ediff-mouse-event-p event)
  1293.      (if ediff-xemacs-p
  1294.          (event-buffer event)
  1295.        (window-buffer (posn-window (event-start event)))))
  1296.     ((ediff-key-press-event-p event)
  1297.      (current-buffer))
  1298.     (t (error))))
  1299.    
  1300.     
  1301. (defsubst ediff-frame-iconified-p (frame)
  1302.   (if (and (ediff-window-display-p) (frame-live-p frame))
  1303.       (if ediff-xemacs-p
  1304.       (frame-iconified-p frame)
  1305.     (eq (frame-visible-p frame) 'icon))))
  1306.     
  1307. (defsubst ediff-window-visible-p (wind)
  1308.   ;; under TTY, window-live-p also means window is visible
  1309.   (and (window-live-p wind)
  1310.        (or (not (ediff-window-display-p))
  1311.        (frame-visible-p (window-frame wind)))))
  1312.   
  1313.  
  1314. (defsubst ediff-frame-char-width (frame)
  1315.   (if ediff-xemacs-p
  1316.       (/ (frame-pixel-width frame) (frame-width frame))
  1317.     (frame-char-width frame)))
  1318.     
  1319. (defun ediff-reset-mouse (&optional frame do-not-grab-mouse)
  1320.   (or frame (setq frame (selected-frame)))
  1321.   (if (ediff-window-display-p)
  1322.       (let ((frame-or-wind frame))
  1323.     (if ediff-xemacs-p 
  1324.         (setq frame-or-wind (frame-selected-window frame)))
  1325.     (or do-not-grab-mouse
  1326.         ;; don't set mouse if the user said to never do this
  1327.         (not ediff-grab-mouse) 
  1328.         ;; Don't grab on quit, if the user doesn't want to.
  1329.         ;; If ediff-grab-mouse = t, then mouse won't be grabbed for
  1330.         ;; sessions that are not part of a group (this is done in
  1331.         ;; ediff-recenter). The condition below affects only terminating
  1332.         ;; sessions in session groups (in which case mouse is warped into
  1333.         ;; a meta buffer).
  1334.         (and (eq ediff-grab-mouse 'maybe)
  1335.          (memq this-command '(ediff-quit ediff-update-diffs)))
  1336.         (set-mouse-position frame-or-wind 1 0))
  1337.     )))
  1338.  
  1339. (defsubst ediff-spy-after-mouse ()
  1340.   (setq ediff-mouse-pixel-position (mouse-pixel-position)))
  1341.  
  1342. ;; It is not easy to find out when the user grabs the mouse, since emacs and
  1343. ;; xemacs behave differently when mouse is not in any frame. Also, this is
  1344. ;; sensitive to when the user grabbed mouse.  Not used for now.
  1345. (defun ediff-user-grabbed-mouse ()
  1346.   (if ediff-mouse-pixel-position
  1347.       (cond ((not (eq (car ediff-mouse-pixel-position)
  1348.               (car (mouse-pixel-position)))))
  1349.         ((and (car (cdr ediff-mouse-pixel-position))
  1350.           (car (cdr (mouse-pixel-position)))
  1351.           (cdr (cdr ediff-mouse-pixel-position))
  1352.           (cdr (cdr (mouse-pixel-position))))
  1353.          (not (and (< (abs (- (car (cdr ediff-mouse-pixel-position))
  1354.                   (car (cdr (mouse-pixel-position)))))
  1355.               ediff-mouse-pixel-threshold)
  1356.                (< (abs (- (cdr (cdr ediff-mouse-pixel-position))
  1357.                   (cdr (cdr (mouse-pixel-position)))))
  1358.               ediff-mouse-pixel-threshold))))
  1359.         (t nil))))
  1360.     
  1361. (defsubst ediff-frame-char-height (frame)
  1362.   (if ediff-xemacs-p
  1363.       (glyph-height ediff-H-glyph (selected-window frame))
  1364.     (frame-char-height frame)))
  1365.     
  1366.  
  1367. (defsubst ediff-empty-overlay-p (overl)
  1368.   (= (ediff-overlay-start overl) (ediff-overlay-end overl)))
  1369.  
  1370. ;; like overlay-buffer in Emacs. In XEmacs, returns nil if the extent is
  1371. ;; dead. Otherwise, works like extent-buffer
  1372. (defun ediff-overlay-buffer (overl)
  1373.   (if ediff-emacs-p
  1374.       (overlay-buffer overl)
  1375.     (and (extent-live-p overl) (extent-object overl))))
  1376.  
  1377. ;; like overlay-get in Emacs. In XEmacs, returns nil if the extent is
  1378. ;; dead. Otherwise, like extent-property
  1379. (defun ediff-overlay-get (overl property)
  1380.   (if ediff-emacs-p
  1381.       (overlay-get overl property)
  1382.     (and (extent-live-p overl) (extent-property overl property))))
  1383.   
  1384. ;; t if diff region is empty.
  1385. ;; In case of buffer C, t also if it is not a 3way
  1386. ;; comparison job (merging jobs return t as well).
  1387. (defun ediff-empty-diff-region-p (n buf-type)
  1388.   (if (eq buf-type 'C)
  1389.       (or (not ediff-3way-comparison-job)
  1390.       (= (ediff-get-diff-posn 'C 'beg n)
  1391.          (ediff-get-diff-posn 'C 'end n)))
  1392.     (= (ediff-get-diff-posn buf-type 'beg n)
  1393.        (ediff-get-diff-posn buf-type 'end n))))
  1394.        
  1395. ;; Test if diff region is white space only.
  1396. ;; If 2-way job and buf-type = C, then returns t.
  1397. (defun ediff-whitespace-diff-region-p (n buf-type)
  1398.   (or (and (eq buf-type 'C) (not ediff-3way-job))
  1399.       (ediff-empty-diff-region-p n buf-type)
  1400.       (let ((beg (ediff-get-diff-posn buf-type 'beg n))
  1401.         (end (ediff-get-diff-posn buf-type 'end n)))
  1402.     (ediff-eval-in-buffer (ediff-get-buffer buf-type)
  1403.       (save-excursion
  1404.         (goto-char beg)
  1405.         (skip-chars-forward ediff-whitespace)
  1406.         (>= (point) end))))))
  1407.         
  1408. ;; temporarily uses DIR to abbreviate file name
  1409. ;; if DIR is nil, use default-directory
  1410. (defun ediff-abbreviate-file-name (file &optional dir)
  1411.   (cond ((stringp dir)
  1412.      (let ((directory-abbrev-alist (list (cons dir ""))))
  1413.        (abbreviate-file-name file)))
  1414.     (ediff-emacs-p (abbreviate-file-name file))
  1415.     (t ; XEmacs requires addl argument
  1416.      (abbreviate-file-name file t))))
  1417.  
  1418. ;; Takes a directory and returns the parent directory.
  1419. ;; does nothing to `/'. If the ARG is a regular file,
  1420. ;; strip the file AND the last dir.
  1421. (defun ediff-strip-last-dir (dir)
  1422.   (if (not (stringp dir)) (setq dir default-directory))
  1423.   (setq dir (expand-file-name dir))
  1424.   (or (file-directory-p dir) (setq dir (file-name-directory dir)))
  1425.   (let* ((pos (1- (length dir)))
  1426.      (last-char (aref dir pos)))
  1427.     (if (and (> pos 0) (= last-char ?/))
  1428.     (setq dir (substring dir 0 pos)))
  1429.     (ediff-abbreviate-file-name (file-name-directory dir))))
  1430.  
  1431. (defun ediff-truncate-string-left (str newlen)
  1432.   ;; leave space for ... on the left
  1433.   (let ((len (length str))
  1434.     substr)
  1435.     (if (<= len newlen)
  1436.     str
  1437.       (setq newlen (max 0 (- newlen 3)))
  1438.       (setq substr (substring str (max 0 (- len 1 newlen))))
  1439.       (concat "..." substr))))
  1440.  
  1441. (defun ediff-abbrev-jobname (jobname)
  1442.   (cond ((eq jobname 'ediff-directories)
  1443.      "Compare two directories")
  1444.     ((eq jobname 'ediff-files)
  1445.      "Compare two files")
  1446.     ((eq jobname 'ediff-buffers)
  1447.      "Compare two buffers")
  1448.     ((eq jobname 'ediff-directories3)
  1449.      "Compare three directories")
  1450.     ((eq jobname 'ediff-files3)
  1451.      "Compare three files")
  1452.     ((eq jobname 'ediff-buffers3)
  1453.      "Compare three buffers")
  1454.     ((eq jobname 'ediff-revision)
  1455.      "Compare file with a version")
  1456.     ((eq jobname 'ediff-directory-revisions)
  1457.      "Compare dir files with versions")
  1458.     ((eq jobname 'ediff-merge-directory-revisions)
  1459.      "Merge dir files with versions")
  1460.     ((eq jobname 'ediff-merge-directory-revisions-with-ancestor)
  1461.      "Merge dir versions via ancestors")
  1462.     (t
  1463.      (let* ((str (substring (symbol-name jobname) 6))
  1464.         (len (length str))
  1465.         (pos 0))
  1466.        (while (< pos len)
  1467.          (if (= pos 0)
  1468.          (aset str pos (upcase (aref str pos))))
  1469.          (if (= (aref str pos) ?-)
  1470.          (aset str pos ?\ ))
  1471.          (setq pos (1+ pos)))
  1472.        str))))
  1473.   
  1474.  
  1475.     
  1476. (defsubst ediff-get-region-contents (n buf-type ctrl-buf &optional start end)
  1477.   (ediff-eval-in-buffer 
  1478.       (ediff-eval-in-buffer ctrl-buf (ediff-get-buffer buf-type))
  1479.     (buffer-substring
  1480.      (or start (ediff-get-diff-posn buf-type 'beg n ctrl-buf))
  1481.      (or end (ediff-get-diff-posn buf-type 'end n ctrl-buf)))))
  1482.   
  1483. ;; If ediff modified mode line, strip the modification
  1484. (defsubst ediff-strip-mode-line-format ()
  1485.   (if (member (car mode-line-format) '(" A: " " B: " " C: " " Ancestor: "))
  1486.       (setq mode-line-format (nth 2 mode-line-format))))
  1487.  
  1488. ;; Verify that we have a difference selected.
  1489. (defsubst ediff-valid-difference-p (&optional n)
  1490.   (or n (setq n ediff-current-difference))
  1491.   (and (>= n 0) (< n ediff-number-of-differences)))
  1492.   
  1493. (defsubst ediff-show-all-diffs (n)
  1494.   "Don't skip difference regions."
  1495.   nil)
  1496.  
  1497. (defsubst Xor (a b)
  1498.   (or (and a (not b)) (and (not a) b)))
  1499.  
  1500. (defsubst ediff-message-if-verbose (string &rest args)
  1501.   (if ediff-verbose-p
  1502.       (apply 'message string args)))
  1503.  
  1504. (defun ediff-file-attributes (filename attr-number)
  1505.   (let ((handler (find-file-name-handler filename 'find-file-noselect)))
  1506.     (if (and handler (string-match "ange-ftp" (format "%S" handler)))
  1507.     -1
  1508.       (nth attr-number (file-attributes filename)))))
  1509. (defsubst ediff-file-size (filename)
  1510.   (ediff-file-attributes filename 7))
  1511. (defsubst ediff-file-modtime (filename)
  1512.   (ediff-file-attributes filename 5))
  1513.  
  1514.  
  1515.  
  1516.  
  1517.      
  1518. (provide 'ediff-init)
  1519.  
  1520.  
  1521. ;;; ediff-init.el  ends here
  1522.